//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension IoT1ClickDevicesService {
    // MARK: Enums

    // MARK: Shapes

    public struct Attributes: AWSDecodableShape {
        public init() {}
    }

    public struct ClaimDevicesByClaimCodeRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "claimCode", location: .uri("ClaimCode"))
        ]

        /// The claim code, starting with "C-", as provided by the device manufacturer.
        public let claimCode: String

        public init(claimCode: String) {
            self.claimCode = claimCode
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ClaimDevicesByClaimCodeResponse: AWSDecodableShape {
        /// The claim code provided by the device manufacturer.
        public let claimCode: String?
        /// The total number of devices associated with the claim code that has been processed in the claim request.
        public let total: Int?

        public init(claimCode: String? = nil, total: Int? = nil) {
            self.claimCode = claimCode
            self.total = total
        }

        private enum CodingKeys: String, CodingKey {
            case claimCode
            case total
        }
    }

    public struct DescribeDeviceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String

        public init(deviceId: String) {
            self.deviceId = deviceId
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeDeviceResponse: AWSDecodableShape {
        /// Device details.
        public let deviceDescription: DeviceDescription?

        public init(deviceDescription: DeviceDescription? = nil) {
            self.deviceDescription = deviceDescription
        }

        private enum CodingKeys: String, CodingKey {
            case deviceDescription
        }
    }

    public struct Device: AWSDecodableShape {
        /// The user specified attributes associated with the device for an event.
        public let attributes: Attributes?
        /// The unique identifier of the device.
        public let deviceId: String?
        /// The device type, such as "button".
        public let type: String?

        public init(attributes: Attributes? = nil, deviceId: String? = nil, type: String? = nil) {
            self.attributes = attributes
            self.deviceId = deviceId
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case attributes
            case deviceId
            case type
        }
    }

    public struct DeviceDescription: AWSDecodableShape {
        /// The ARN of the device.
        public let arn: String?
        /// An array of zero or more elements of DeviceAttribute objects providing user specified device attributes.
        public let attributes: [String: String]?
        /// The unique identifier of the device.
        public let deviceId: String?
        /// A Boolean value indicating whether or not the device is enabled.
        public let enabled: Bool?
        /// A value between 0 and 1 inclusive, representing the fraction of life remaining for the device.
        public let remainingLife: Double?
        /// The tags currently associated with the AWS IoT 1-Click device.
        public let tags: [String: String]?
        /// The type of the device, such as "button".
        public let type: String?

        public init(arn: String? = nil, attributes: [String: String]? = nil, deviceId: String? = nil, enabled: Bool? = nil, remainingLife: Double? = nil, tags: [String: String]? = nil, type: String? = nil) {
            self.arn = arn
            self.attributes = attributes
            self.deviceId = deviceId
            self.enabled = enabled
            self.remainingLife = remainingLife
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case attributes
            case deviceId
            case enabled
            case remainingLife
            case tags
            case type
        }
    }

    public struct DeviceEvent: AWSDecodableShape {
        /// An object representing the device associated with the event.
        public let device: Device?
        /// A serialized JSON object representing the device-type specific event.
        public let stdEvent: String?

        public init(device: Device? = nil, stdEvent: String? = nil) {
            self.device = device
            self.stdEvent = stdEvent
        }

        private enum CodingKeys: String, CodingKey {
            case device
            case stdEvent
        }
    }

    public struct DeviceMethod: AWSEncodableShape & AWSDecodableShape {
        /// The type of the device, such as "button".
        public let deviceType: String?
        /// The name of the method applicable to the deviceType.
        public let methodName: String?

        public init(deviceType: String? = nil, methodName: String? = nil) {
            self.deviceType = deviceType
            self.methodName = methodName
        }

        private enum CodingKeys: String, CodingKey {
            case deviceType
            case methodName
        }
    }

    public struct FinalizeDeviceClaimRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String
        /// A collection of key/value pairs defining the resource tags. For example, { "tags": {"key1": "value1", "key2": "value2"} }. For more information, see AWS Tagging Strategies.
        public let tags: [String: String]?

        public init(deviceId: String, tags: [String: String]? = nil) {
            self.deviceId = deviceId
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct FinalizeDeviceClaimResponse: AWSDecodableShape {
        /// The device's final claim state.
        public let state: String?

        public init(state: String? = nil) {
            self.state = state
        }

        private enum CodingKeys: String, CodingKey {
            case state
        }
    }

    public struct GetDeviceMethodsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String

        public init(deviceId: String) {
            self.deviceId = deviceId
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetDeviceMethodsResponse: AWSDecodableShape {
        /// List of available device APIs.
        public let deviceMethods: [DeviceMethod]?

        public init(deviceMethods: [DeviceMethod]? = nil) {
            self.deviceMethods = deviceMethods
        }

        private enum CodingKeys: String, CodingKey {
            case deviceMethods
        }
    }

    public struct InitiateDeviceClaimRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String

        public init(deviceId: String) {
            self.deviceId = deviceId
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct InitiateDeviceClaimResponse: AWSDecodableShape {
        /// The device's final claim state.
        public let state: String?

        public init(state: String? = nil) {
            self.state = state
        }

        private enum CodingKeys: String, CodingKey {
            case state
        }
    }

    public struct InvokeDeviceMethodRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String
        /// The device method to invoke.
        public let deviceMethod: DeviceMethod?
        /// A JSON encoded string containing the device method request parameters.
        public let deviceMethodParameters: String?

        public init(deviceId: String, deviceMethod: DeviceMethod? = nil, deviceMethodParameters: String? = nil) {
            self.deviceId = deviceId
            self.deviceMethod = deviceMethod
            self.deviceMethodParameters = deviceMethodParameters
        }

        private enum CodingKeys: String, CodingKey {
            case deviceMethod
            case deviceMethodParameters
        }
    }

    public struct InvokeDeviceMethodResponse: AWSDecodableShape {
        /// A JSON encoded string containing the device method response.
        public let deviceMethodResponse: String?

        public init(deviceMethodResponse: String? = nil) {
            self.deviceMethodResponse = deviceMethodResponse
        }

        private enum CodingKeys: String, CodingKey {
            case deviceMethodResponse
        }
    }

    public struct ListDeviceEventsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId")),
            AWSMemberEncoding(label: "_fromTimeStamp", location: .querystring("fromTimeStamp")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken")),
            AWSMemberEncoding(label: "_toTimeStamp", location: .querystring("toTimeStamp"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String
        /// The start date for the device event query, in ISO8061 format. For example, 2018-03-28T15:45:12.880Z
        @CustomCoding<ISO8601DateCoder>
        public var fromTimeStamp: Date
        /// The maximum number of results to return per request. If not set, a default value of 100 is used.
        public let maxResults: Int?
        /// The token to retrieve the next set of results.
        public let nextToken: String?
        /// The end date for the device event query, in ISO8061 format. For example, 2018-03-28T15:45:12.880Z
        @CustomCoding<ISO8601DateCoder>
        public var toTimeStamp: Date

        public init(deviceId: String, fromTimeStamp: Date, maxResults: Int? = nil, nextToken: String? = nil, toTimeStamp: Date) {
            self.deviceId = deviceId
            self.fromTimeStamp = fromTimeStamp
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.toTimeStamp = toTimeStamp
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListDeviceEventsResponse: AWSDecodableShape {
        /// An array of zero or more elements describing the event(s) associated with the device.
        public let events: [DeviceEvent]?
        /// The token to retrieve the next set of results.
        public let nextToken: String?

        public init(events: [DeviceEvent]? = nil, nextToken: String? = nil) {
            self.events = events
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case events
            case nextToken
        }
    }

    public struct ListDevicesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceType", location: .querystring("deviceType")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The type of the device, such as "button".
        public let deviceType: String?
        /// The maximum number of results to return per request. If not set, a default value of 100 is used.
        public let maxResults: Int?
        /// The token to retrieve the next set of results.
        public let nextToken: String?

        public init(deviceType: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.deviceType = deviceType
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListDevicesResponse: AWSDecodableShape {
        /// A list of devices.
        public let devices: [DeviceDescription]?
        /// The token to retrieve the next set of results.
        public let nextToken: String?

        public init(devices: [DeviceDescription]? = nil, nextToken: String? = nil) {
            self.devices = devices
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case devices
            case nextToken
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn"))
        ]

        /// The ARN of the resource.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// A collection of key/value pairs defining the resource tags. For example, { "tags": {"key1": "value1", "key2": "value2"} }. For more information, see AWS Tagging Strategies.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn"))
        ]

        /// The ARN of the resource.
        public let resourceArn: String
        /// A collection of key/value pairs defining the resource tags. For example, { "tags": {"key1": "value1", "key2": "value2"} }. For more information, see AWS Tagging Strategies.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct UnclaimDeviceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String

        public init(deviceId: String) {
            self.deviceId = deviceId
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UnclaimDeviceResponse: AWSDecodableShape {
        /// The device's final claim state.
        public let state: String?

        public init(state: String? = nil) {
            self.state = state
        }

        private enum CodingKeys: String, CodingKey {
            case state
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("tagKeys"))
        ]

        /// The ARN of the resource.
        public let resourceArn: String
        /// A collections of tag keys. For example, {"key1","key2"}
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UpdateDeviceStateRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "deviceId", location: .uri("DeviceId"))
        ]

        /// The unique identifier of the device.
        public let deviceId: String
        /// If true, the device is enabled. If false, the device is disabled.
        public let enabled: Bool?

        public init(deviceId: String, enabled: Bool? = nil) {
            self.deviceId = deviceId
            self.enabled = enabled
        }

        private enum CodingKeys: String, CodingKey {
            case enabled
        }
    }

    public struct UpdateDeviceStateResponse: AWSDecodableShape {
        public init() {}
    }
}

// MARK: - Errors

/// Error enum for IoT1ClickDevicesService
public struct IoT1ClickDevicesServiceErrorType: AWSErrorType {
    enum Code: String {
        case forbiddenException = "ForbiddenException"
        case internalFailureException = "InternalFailureException"
        case invalidRequestException = "InvalidRequestException"
        case preconditionFailedException = "PreconditionFailedException"
        case rangeNotSatisfiableException = "RangeNotSatisfiableException"
        case resourceConflictException = "ResourceConflictException"
        case resourceNotFoundException = "ResourceNotFoundException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize IoT1ClickDevicesService
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var forbiddenException: Self { .init(.forbiddenException) }
    public static var internalFailureException: Self { .init(.internalFailureException) }
    public static var invalidRequestException: Self { .init(.invalidRequestException) }
    public static var preconditionFailedException: Self { .init(.preconditionFailedException) }
    public static var rangeNotSatisfiableException: Self { .init(.rangeNotSatisfiableException) }
    public static var resourceConflictException: Self { .init(.resourceConflictException) }
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
}

extension IoT1ClickDevicesServiceErrorType: Equatable {
    public static func == (lhs: IoT1ClickDevicesServiceErrorType, rhs: IoT1ClickDevicesServiceErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension IoT1ClickDevicesServiceErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
